package com.fuhailiu.opengl.renders;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import android.content.Context;
import android.opengl.GLES30;
import android.opengl.GLSurfaceView;
import android.opengl.GLSurfaceView.Renderer;
import android.view.MotionEvent;
import android.view.SurfaceHolder;

import com.fuhailiu.opengl.utils.LogUtil;
import com.fuhailiu.opengl.utils.MatrixUtil;
import com.fuhailiu.opengl.view.GLViewGroup;

public abstract class AbsRender implements Renderer {

	private final String TAG = getClass().getSimpleName();

	protected Context mContext;

	protected GLViewGroup mGLViewGroup;

	protected int mSurfaceWidth, mSurfaceHeight;

	public AbsRender(Context context) {
		mContext = context;
	}

	@Override
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		LogUtil.LogD(TAG, "onSurfaceCreated   <---");

		// 设置屏幕背景色
		float[] bgColor = getBackgroundColor();
		GLES30.glClearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]);

		// 打开深度检测
		GLES30.glEnable(GLES30.GL_DEPTH_TEST);

		// 初始化矩阵存储类
		MatrixUtil.initStack(16);

		LogUtil.LogD(TAG, "onSurfaceCreated   --->");
	}

	@Override
	public void onSurfaceChanged(GL10 gl, int width, int height) {
		LogUtil.LogD(TAG, "onSurfaceChanged   <---");
		LogUtil.LogD(TAG, "onSurfaceChanged   width = " + width + ", height = " + height);

		mSurfaceWidth = width;
		mSurfaceHeight = height;

		// 设置视窗大小及位置
		GLES30.glViewport(0, 0, width, height);

		// 设置摄像机位置
		float[] eye = getEyePosition();
		MatrixUtil.setLookAt(eye[0], eye[1], eye[2], eye[3], eye[4], eye[5], eye[6], eye[7], eye[8]);

		// 设置透视投影
		float ratio = 1.0f * width / height;
		float[] project = getProjectPosition(ratio);
		if (useOrtho()) {
			MatrixUtil.setProjectOrtho(project[0], project[1], project[2], project[3], project[4], project[5]);
		} else {
			MatrixUtil.setProjectFrustum(project[0], project[1], project[2], project[3], project[4], project[5]);
		}

		// 创建世界模型
		mGLViewGroup = makeWorld(mContext);

		LogUtil.LogD(TAG, "onSurfaceChanged   --->");
	}

	@Override
	public void onDrawFrame(GL10 gl) {
		// 清除深度缓冲与颜色缓冲
		GLES30.glClear(GLES30.GL_DEPTH_BUFFER_BIT | GLES30.GL_COLOR_BUFFER_BIT | GLES30.GL_STENCIL_BUFFER_BIT);

		// 绘制图形
		if (null != mGLViewGroup) {
			mGLViewGroup.draw(gl);
		}
	}

	public void onSurfaceDestroyed(SurfaceHolder holder) {
		LogUtil.LogD(TAG, "onSurfaceDestroyed   <---");
		if (null != mGLViewGroup) {
			mGLViewGroup.release();
		}
		LogUtil.LogD(TAG, "onSurfaceDestroyed   --->");
	}

	/**
	 * RGBA
	 * */
	protected float[] getBackgroundColor() {
		return new float[] { 0.5f, 0.5f, 0.5f, 1 };
	}

	/**
	 * 摄像机位置
	 * 
	 * @param eyeX
	 *            摄像机位置x
	 * @param eyeY
	 *            摄像机位置y
	 * @param eyeZ
	 *            摄像机位置z
	 * @param centerX
	 *            摄像机目标点x
	 * @param centerY
	 *            摄像机目标点y
	 * @param centerZ
	 *            摄像机目标点z
	 * @param upX
	 *            摄像机UP向量x分量
	 * @param upY
	 *            摄像机UP向量y分量
	 * @param upZ
	 *            摄像机UP向量z分量
	 */
	protected float[] getEyePosition() {
		return new float[] { 0, 0, 2, 0f, 0f, 0f, 0f, 1.0f, 0.0f };
	}

	/**
	 * 投影
	 * 
	 * @param left
	 *            near面的left
	 * @param right
	 *            near面的right
	 * @param bottom
	 *            near面的bottom
	 * @param top
	 *            near面的top
	 * @param near
	 *            near面距离
	 * @param far
	 *            far面距离
	 */
	protected float[] getProjectPosition(float ratio) {
		return new float[] { -ratio, ratio, -1, 1, 1.0f, 3.0f };
	}

	protected boolean useOrtho() {
		return true;
	}

	protected abstract GLViewGroup makeWorld(Context context);

	public int getRenderMode() {
		return GLSurfaceView.RENDERMODE_CONTINUOUSLY;
	}

	public void onTouchEvent(MotionEvent event) {
	}

	public String[] getMenuInfo() {
		return null;
	}

	public void onMenuSelected(String title) {
	}

}
